#ifndef _MEMDC_H_
#define _MEMDC_H_

//////////////////////////////////////////////////
// CMemDC - memory DC
//
// Author: Keith Rule
// Email:  keithr@europa.com
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// This class implements a memory Device Context

class CMemDC : public CDC 
{
private:
    CBitmap*	m_bitmap;
    CBitmap*	m_oldBitmap;
    CDC*		m_pDC;
    CRect		m_rcBounds;
    CPoint		m_ptOrg;
public:
    CMemDC(CDC* pDC, const CRect& rcBounds) : CDC()
    {
        CreateCompatibleDC(pDC);
        m_bitmap = new CBitmap;
        m_bitmap->CreateCompatibleBitmap(pDC, rcBounds.Width(), rcBounds.Height());
        m_oldBitmap = SelectObject(m_bitmap);
        m_pDC = pDC;
        m_rcBounds = rcBounds;
        m_ptOrg = SetWindowOrg(rcBounds.TopLeft());
    }
    ~CMemDC() 
    {		
        SetWindowOrg(m_ptOrg);
        m_pDC->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(), 
            this, 0, 0, SRCCOPY);
        SelectObject(m_oldBitmap);
        if (m_bitmap != NULL) 
            delete m_bitmap;
        DeleteDC();

    }
    CMemDC* operator->() 
    {
        return this;
    }
};

class CStaticMemDC : public CDC
{
private:
    CBitmap*	m_bitmap;
    CBitmap*	m_oldBitmap;
    CDC*		m_pDC;
    CRect		m_rcBounds;
    CPoint		m_ptOrg;
    CWnd*       m_pWnd;
public:
    CStaticMemDC() : CDC(),m_rcBounds(0,0,0,0)
    {
        m_bitmap = 0;
    }
    ~CStaticMemDC()
    {
        if(m_bitmap) {
            delete m_bitmap;
            m_bitmap = 0;
        }
        DeleteDC();
    }
    void DetectResize(CWnd* pWnd)
    {
        CRect rc;
        pWnd->GetClientRect(&rc);
        if(rc != m_rcBounds)
        {
            if(m_bitmap)
                delete m_bitmap;
            m_rcBounds = rc;
            m_bitmap = new CBitmap;
            CDC* pDC = pWnd->GetDC();
            m_bitmap->CreateCompatibleBitmap(pDC, m_rcBounds.Width(), m_rcBounds.Height());
            pWnd->ReleaseDC(pDC);
        }
    }
    void Install(CWnd* pWnd)
    {
        DetectResize(pWnd);
        m_pWnd = pWnd;
        m_pDC = pWnd->GetDC();
        CreateCompatibleDC(m_pDC);
        m_oldBitmap = SelectObject(m_bitmap);
        m_ptOrg = SetWindowOrg(m_rcBounds.TopLeft());
    }
    void Uninstall()
    {
        SetWindowOrg(m_ptOrg);
        m_pDC->BitBlt(m_rcBounds.left, m_rcBounds.top, m_rcBounds.Width(), m_rcBounds.Height(), 
            this, 0, 0, SRCCOPY);
        SelectObject(m_oldBitmap);
        m_pWnd->ReleaseDC(m_pDC);
        DeleteDC();
    }
};

#endif